Website Summary Files Commits Branches @commit @diff @stats
path: root / Sem. 08
NameSize
..
Complex114 Blog stats plain
NVector114 Blog stats plain
README.md8.0 KiBlog stats plain blame

Предефиниране на оператори. Приятелски класове и функции. Mutable член-данни.

Oператори

Видове оператори.

в C++ има два вида оператори:

  • Унарни (на един аргумент)
  • Бинарни (на два аргумента)

Операторите се характеризират с:

  • Приоритет
  • Асоциативност
  • Позиция на оператора спярмо аргумента - префиксен, инфиксен и суфиксен

Списъка на операторите в C++:

Оператор Асоциативност
() [] -> . ++ - - лявоасоциативен
+ - ! ~ ++ - - (type)* & sizeof дясноасоциативен
* / % лявоасоциативен
+ - лявоасоциативен
<< >> лявоасоциативен
< <= > >= лявоасоциативен
== != лявоасоциативен
& лявоасоциативен
^ лявоасоциативен
| лявоасоциативен
&& лявоасоциативен
|| лявоасоциативен
?: дясноасоциативен
= += -= *= /= %= >>= <<= &= ^= дясноасоциативен

Предефиниране на оператор (пример)

Complex& Complex::operator+=(const Complex& other)
{
    real += other.real;
    im += other.im;
    return *this;
}
 ```
Вече може да правим следното:
```c++
int main()
{
    Complex c(1,3); //1 + 3i;
    Complex c2(10,20) // 10 + 2i;
    c += c2 // now c is 11 + 5i
}
 ```
При предефинирането на оператор **не могат** да се променят *приоритетът*, *асоциативността*, броят и позицията на *аргументите* му.

## Приятелски класове и приятелски функции
Декларират се с на запазената дума **friend** пред прототипа на функцията.  
Даденият friend-клас/фунцкия има достъп до всички компоненти на класа. 
Т.е. всички членове на класа са public за friend-класовете/функциите приятели.
### Приятелски функции (пример)

 ```c++
class Complex
{

private:
    double real;
    double im;
public:
    friend double getModulos(const Complex& other);
    .
    .
    .
}
 ```
  ```c++

double getModulos(const Complex& other)
{
    return sqrt((other.real – other.real) * (other.real – other.real) + (other.im – other.im ) * (other.im – other.im));
}

Mutable (пример)

Спецификатора mutable е приложен само в С++. Той позволява на член на обект да предефинира константността. Така mutable член на const обект не е const и може да бъде изменян. ```c++ struct Test { private: mutable int n; public: void f() const { n++; }

};

int main() { const Test t;

t.f();

} ```

Задачи

Задача 1: Реализирайте клас Nvector, който ще се използва за работа с математически вектор. Предефинирайте оператори със следната функционалност: - Събиране на вектори. - Изваждане на вектори. - Умножение на вектор със скалар. - Проверка дали два вектора са успоредни. - Проверка дали два вектора са перпендикулярни. - Взимане на дължина на вектор. - Достъп до произволен елемент на вектор. - Вход и изход от потоци.

```c++ int main() { Nvector v(4); cin >> v;

Nvector v2(4);
cin >> v;

Nvector result = v + v2;

cout << result << endl;

} ``` Релизирайте клас двумерната декартова координатна система, която приема 2 вектора, които са нейният базис. Реализрайте следните функции: - Връща вектор в базиса по подадени 2 координата. - По подаден вектор връща координатите му в базиса.

```c++ int main() { Nvector v(4); v[0] = 2; v[1] = 1;

Nvector v2(4);
v2[0] = 3;
v2[1] = 1;

twoDimCoordSystem s(v1, v2);

cout << s1.getVectorByCoordinates(7, 4); // [26, 11]

cout << s1.getCoordinatesByVector(7, 4); // [5, -1]

cout << result << endl;

} ```

Задача 2: Реализирайте клас ComplexNumber, който ще се използва за работа с комплексни числа. Предефинирайте оператори със следната функционалност: - Събиране на комплексни числа. - Изваждане на комплексни числа. - Умножение на комплексни числа. - Деление на комплексни числа - Вход и изход от потоци.

```c++

int main() { ComplexNumber c; cin >> c;

ComplexNumber c2;
cin >> c2;

ComplexNumber result = c2 / c;

cout << result << endl;

} ``` Задача 3: Релизирайте клас - множество(без повторение) от думи от малки/главни латински букви и цифри. В колекцията ви търсенето трябва да е с логаритмична сложност. Предефинирайте оператори:

  • += и +. Събиране на две колекции.
  • -= и -. От думите на лявата колекция, се премахват тези, които участват в дясната.
  • [], който приема дума и връща дали стрингът е в колекцията (очакваме логаритмично време).
  • *= за добавяне на дума
  • /= за премахване на дума.
  • << (поток за изход. Отпечатва всички думи в сортиран вид).
  • >> (поток за вход. Приема думa, която да се добави в речника).

Важно! Копирането на стрингове е бавна операция! Помислете как да организирате данните, за да имате логаритмично търсене на дума и при добавяне на нова дума да правите минимален брой копирания на стрингове!

```c++

int main() { StringPool dict; ((dict = "Ivan") = "Petur") *= "Alex"; std::cout << dict << std::endl; // {Alex, Ivan, Petur} std::cout << dict["Alex"] << " " << dict["abc"] << std::endl; // 1 0

StringPool dict2;
((dict2 *= "Zebra") *= "Alex");

StringPool result = dict + dict2;
std::cout << result << std::endl; // {Alex, Ivan, Petur, Zebra}

StringPool result2 = dict - dict2;
std::cout << result2 << std::endl; // {Ivan, Petur}

"NewWOrd" >> result2;
result2 /= "NonExistingWord";
    std::cout << result2 << std::endl;  //{Ivan, NewWOrd, Petur}
"Job" >> result2; 
std::cout << result2 << std::endl;  //{Ivan, Job, NewWOrd, Petur}

} ```